using System.Collections.Generic;
using Gameplay.PVE.Config;
using Gameplay.PVE.Entity;
using UnityEngine;

namespace Gameplay.PVE.Skill
{
    public class Grenade : SkillBullet
    {
        //手雷类型，抛物线，落地生效
        private Vector3 accelerate;
        private float accelerateTime;
        private float startAccelerateTime;
        private Vector3 additionalSpeed;
        private Vector3 startPosition;
        private float flyTime;

        private float startFlyTime = 0;

        private Transform parent;

        private Vector3 angle;
        private Vector3 angleSpeed;

        private Vector3 throwBeginSpeed;
        private Vector3 throwVh;
        private Vector3 lastHandPosition;

        private float gravity = 10;

        private GameObject targetObj;

        public void SetStartParentAndTargets(Transform parent,List<UnitBase> targetUnits)
        {
            this.parent = parent;
            this.targetUnits = targetUnits;
        }

        public override void Initialize(PveSkillBulletConfig config, PveSkillConfig skillConfig,SkillBase skill, Vector3 startPosition, Vector3 offset, Vector3 angle,
            UnitBase source)
        {
            base.Initialize(config, skillConfig,skill, startPosition, offset, angle, source);
            this.startPosition = startPosition + offset;
            this.startPosition.y = 0;
            flyTime = 0;
            if (config.y_offset > 0)
            {
                accelerateTime = Vector3.Distance(this.startPosition, targetPosition) / config.speed;
                float acValue = 10;
                float minHeight = config.y_offset - offset.y;
                float minAc = minHeight * 2 / (accelerateTime / 2) / (accelerateTime / 2);
                if (acValue < minAc)
                {
                    acValue = minAc;
                }
                accelerate = new Vector3(0,acValue,0);
                
                additionalSpeed = accelerate * accelerateTime / 2;
                startAccelerateTime = currentTime;
                bullet.transform.position = startPosition + offset;
                lastPosition = startPosition + offset;
            }

            if (parent != null)
            {
                bullet.transform.SetParent(parent);
                bullet.transform.localPosition = Vector3.zero;
                bullet.transform.forward = speed;
            }
            startFlyTime = config.in_hand_time + currentTime;
            angle = Vector3.zero;
            lastHandPosition = startPosition;
            angleSpeed = new Vector3(config.angle_speed,0,0);
            speed += additionalSpeed;
        }

        public override void CheckStartHit()
        {
            
        }

        public override void Update(float deltaTime)
        {
            lastTime = currentTime;
            if (bullet == null) return;     
            
            if (currentTime < startFlyTime)
            {
                if (source!=null && source.Data.isDead)
                {
                    Dispose(true);
                }

                var position = bullet.transform.position;
                throwBeginSpeed = position - lastHandPosition;
                lastHandPosition = position;
                return;
            }
            else if (startFlyTime != 0)
            {
                startFlyTime = 0;
                bullet.transform.SetParent(PveScene.pveRootTrans);
                startPosition = bullet.transform.position;
                lastPosition = startPosition;
                /*throwBeginSpeed = (startPosition - lastHandPosition).normalized;

                if (throwBeginSpeed.y < 0 || true)
                {
                    throwBeginSpeed.y = 0;
                    throwBeginSpeed = throwBeginSpeed.normalized;
                }*/
                throwBeginSpeed = (targetPosition - startPosition).normalized;
                //throwBeginSpeed.y = 1;//0;//Random.Range(0, 0.5f);
                throwBeginSpeed.y = Mathf.Abs(startPosition.y - lastHandPosition.y);//Random.Range(0,0.1f);
                throwBeginSpeed = throwBeginSpeed.normalized;

                var vh = throwBeginSpeed.y;
                var vv = Mathf.Sqrt(throwBeginSpeed.x * throwBeginSpeed.x + (throwBeginSpeed.z * throwBeginSpeed.z));

                var g = gravity;
                var start = startPosition;
                var h = start.y;
                start.y = 0;
                var d = Vector3.Distance(start, targetPosition);
                var vt = Mathf.Sqrt(2 * g * h + vh * vh);

                var a = vh*vh;
                var b = 2 * g * h;
                var c = ((d * g - vh) / vv) * ((d * g - vh) / vv);

                var speedValue = 0f;
                /*if (a == 0)
                {
                    speedValue = d / vv / Mathf.Sqrt(2 * h / g);
                }
                else*/
                {
                    speedValue = Mathf.Sqrt(d * d * g / (2 * h * vv * vv + 2 * d * vh * vv));
                    //speedValue = Mathf.Sqrt((-b + Mathf.Sqrt(b * b - 4 * a * c)) / (2 * a));
                }
                

                //speedValue = Mathf.Sqrt(((d / vv - vh) * (d / vv - vh) * g * g - 2 * g * h) / vh);
                if (h == 0)
                {
                    speedValue = 10;
                }
                speed = throwBeginSpeed * speedValue;
                angle = bullet.transform.localEulerAngles;
                return;
            }
            //additionalSpeed = additionalSpeed - accelerate * deltaTime;
            //speed = ((targetPosition - startPosition).normalized) * speedValue + additionalSpeed;
            //speed = throwBeginSpeed;
            speed -= new Vector3(0, 10 * deltaTime, 0);
            flyTime += deltaTime;
            angle -= angleSpeed * deltaTime;
            bullet.transform.localEulerAngles = angle;
            
            if ((speed.y < 0 && bullet.transform.position.y <= 0f))
            {
                additionalSpeed = Vector3.zero;
                bullet.transform.position = new Vector3(bullet.transform.position.x,0.01f,bullet.transform.position.z);
                bullet.transform.forward = new Vector3(bullet.transform.forward.x,0,bullet.transform.forward.z);
                CheckArea();
                CheckSubBullets();
                Dispose();
                GameObject.DestroyImmediate(targetObj);
            }
            UpdatePosition(deltaTime);
            UpdateTrail();
            UpdateTime(deltaTime);
        }
    }
}